package com.addplus.townmall.server.web.provider.serviceimpl.knowledgeModule;

import com.addplus.townmall.server.api.constant.ErrorCode;
import com.addplus.townmall.server.api.exception.ErrorException;
import com.addplus.townmall.server.api.mapper.exam.KnowledgeMapper;
import com.addplus.townmall.server.api.mapper.exam.QuestionMapper;
import com.addplus.townmall.server.api.model.exam.*;
import com.addplus.townmall.server.api.service.web.knowledgeModule.KnowledgeService;
import com.addplus.townmall.server.api.utils.DataUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

@Service(interfaceClass = KnowledgeService.class)
public class KnowLedgeServiceImpl implements KnowledgeService {
    @Autowired
    private KnowledgeMapper knowledgeMapper;
    @Autowired
    private QuestionMapper questionMapper;

    @Override
    public Boolean updateKnowledgeById(Knowledge knowLedge) throws Exception {
        if (knowLedge == null) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        if (knowLedge.getId() == null) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        knowLedge.setGmtModified(new Date());
        if (knowLedge.getPid() != null) {
            Integer pid = knowLedge.getPid();
            if (pid == 0) {
                knowLedge.setIsRoot(1);
                knowLedge.setPath(knowLedge.getId().toString());
                knowLedge.setDept(1);
            } else {
                knowLedge.setIsRoot(0);
                Knowledge areaP = knowledgeMapper.selectById(pid);
                if (areaP != null && StringUtils.isNotBlank(areaP.getPath())) {
                    String path = areaP.getPath();
                    knowLedge.setPath(path.concat("," + knowLedge.getId().toString()));
                }
                knowLedge.setDept(areaP.getDept() + 1);
            }
        }
        knowLedge.setGmtModified(new Date());
        int count = knowledgeMapper.updateById(knowLedge);
        if (count < 0) {
            throw new ErrorException(ErrorCode.SYS_ERROR_DATABASEFAIL);
        }
        return true;
    }

    @Override
    public List<KnowledgeExpand> getKnowledgeListByPid(Integer pid) throws Exception {
        if (DataUtils.EmptyOrNegative(pid)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        List<KnowledgeExpand> knowledgeList = knowledgeMapper.selectKnowledgeListByPid(pid);
        return knowledgeList;
    }

    @Override
    public List<KnowledgeExpand> getKnowledgeByPid(Integer pid) throws Exception {
        if (DataUtils.EmptyOrNegative(pid)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Integer dept;
        if (pid == 0) {
            dept = 1;
        } else {
            Knowledge knowledge = knowledgeMapper.selectById(pid);
            dept = knowledge.getDept() + 1;
        }
        List<Knowledge> knowledgeList = null;
        List<KnowledgeExpand> knowledgeExpList = new ArrayList<>();
        QueryWrapper<Knowledge> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.eq("pid", pid);
        areaQueryWrapper.eq("dept", dept);
        areaQueryWrapper.eq("is_delete", 0);
        areaQueryWrapper.select("id", "knowledge_name", "pid");
        knowledgeList = knowledgeMapper.selectList(areaQueryWrapper);
        if (knowledgeList == null) {
            return null;
        }
        KnowledgeExpand knowledgeExpand = null;
        for (Knowledge knowledge : knowledgeList) {
            knowledgeExpand = new KnowledgeExpand();
            knowledgeExpand.setTitle(knowledge.getKnowledgeName());
            knowledgeExpand.setKey(knowledge.getId());
            knowledgeExpand.setValue(knowledge.getId());
            knowledgeExpList.add(knowledgeExpand);
        }
        return knowledgeExpList;
    }

    @Override
    public IPage<Knowledge> getKnowledgeParentByPage(Integer pageNo, Integer pageSize) throws Exception {
        if (DataUtils.EmptyOrNegative(pageNo, pageSize)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Page page = new Page(pageNo, pageSize);
        QueryWrapper<Knowledge> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.eq("dept", 1);
        areaQueryWrapper.eq("is_delete", 0);
        areaQueryWrapper.select("id", "knowledge_name", "pid");
        IPage areaPage = knowledgeMapper.selectPage(page, areaQueryWrapper);
        if (areaPage == null || areaPage.getRecords() == null || areaPage.getRecords().isEmpty()) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        return areaPage;
    }

    @Override
    public Knowledge addKnowledge(Knowledge knowledge) throws Exception {
        if (knowledge == null) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Integer pid = knowledge.getPid();
        if(pid==null){
            knowledge.setPid(0);
            pid = knowledge.getPid();
        }
        QueryWrapper<Knowledge> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("knowledge_name", knowledge.getKnowledgeName());
        queryWrapper1.eq("pid",knowledge.getPid());
        queryWrapper1.eq("is_delete", 0);
        int hasCount=knowledgeMapper.selectCount(queryWrapper1);
        if(hasCount>0){
            throw new ErrorException(ErrorCode.SYS_ERROR_DATA_EXIT);
        }
        if (pid == 0) {
            knowledge.setIsRoot(1);
            knowledge.setPath("0");
            knowledge.setDept(1);
        } else {
            knowledge.setIsRoot(0);
            QueryWrapper<Knowledge> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", pid);
            queryWrapper.eq("is_delete", 0);
            Knowledge knowLedge1 = knowledgeMapper.selectOne(queryWrapper);
            String path = null;
            if (knowLedge1 != null && StringUtils.isNotBlank(knowLedge1.getPath())) {
                path = knowLedge1.getPath();
            }
            knowledge.setPath(path);
            knowledge.setDept(knowLedge1.getDept() + 1);
        }
        knowledge.setIsDelete(0);
        Date date = new Date();
        knowledge.setGmtCreate(date);
        knowledge.setGmtModified(date);
        int count = knowledgeMapper.insert(knowledge);
        if (count < 0) {
            throw new ErrorException(ErrorCode.SYS_ERROR_DATABASEFAIL);
        }
        QueryWrapper<Knowledge> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("knowledge_name", knowledge.getKnowledgeName());
        queryWrapper.eq("pid",knowledge.getPid());
        queryWrapper.eq("is_delete", 0);
        knowledge = knowledgeMapper.selectOne(queryWrapper);
        if (knowledge.getPath().equals("0")) {
            knowledge.setPath(knowledge.getId().toString());
        } else {
            knowledge.setPath(knowledge.getPath().concat("," + knowledge.getId().toString()));
        }
        knowledgeMapper.updateById(knowledge);
        return knowledge;
    }


    @Override
    public IPage<KnowledgeExpand> getKnowledgeByName(String knowledgeName, Integer pageNo, Integer pageSize) throws Exception {
//        if (DataUtils.EmptyOrNegative(pageNo, pageSize)) {
//            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
//        }
//        if (DataUtils.isEmpty(knowledgeName)) {
//            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
//        }
//        Page page = new Page(pageNo, pageSize);
//        QueryWrapper<Knowledge> areaQueryWrapper = new QueryWrapper<>();
//        areaQueryWrapper.eq("is_delete", 0);
//        areaQueryWrapper.like("knowledge_name", knowledgeName);
//        areaQueryWrapper.select("id", "path", "dept");
//        IPage knowledgePage = knowledgeMapper.selectPage(page, areaQueryWrapper);
//        if (knowledgePage == null || knowledgePage.getRecords() == null || knowledgePage.getRecords().isEmpty()) {
//            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
//        }
//        Integer dept = 100;
//        for (Object o : knowledgePage.getRecords()) {
//            Knowledge knowLedge = (Knowledge) o;
//            if (dept > knowLedge.getDept()) {
//                dept = knowLedge.getDept();
//            }
//        }
//        final Integer deptF = dept;
//
//        List<String> knowLedgePathList = (List<String>) knowledgePage.getRecords().stream().map(o -> {
//            Knowledge knowLedge = (Knowledge) o;
//            return knowLedge.getPath();
//        }).collect(Collectors.toList());
//        //查询当前接口的所有子节点
//        List<KnowledgeExpand> knowledgeExpandList = new ArrayList<>();
//        for (String path : knowLedgePathList) {
//            List<KnowledgeExpand> knowledgeExpands = knowledgeMapper.getKnowLedgeChilderByPath(path);
//            knowledgeExpandList.addAll(knowledgeExpands);
//        }
//        if (knowledgeExpandList == null || knowledgeExpandList.isEmpty()) {
//            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
//        }
//        //根据父节点id分组
//        Map<Integer, List<KnowledgeExpand>> map = knowledgeExpandList.stream().filter(o -> Objects.nonNull(o.getPid())).collect(Collectors.groupingBy(KnowledgeExpand::getPid));
//        //循环处理子节点 构建树状结构
//        knowledgeExpandList.forEach(o -> {
//            if (map.containsKey(o.getId())) {
//                o.setKnowledgeList(map.get(o.getId()));
//            }
//        });
//        List<KnowledgeExpand> result = knowledgeExpandList.stream().filter(o -> o.getDept().equals(deptF)).collect(Collectors.toList());
//        if (result == null || result.isEmpty()) {
//            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
//        }
//        knowledgePage.setRecords(result);
//        return knowledgePage;
        if (DataUtils.EmptyOrNegative(pageNo, pageSize)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        if (DataUtils.isEmpty(knowledgeName)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Page<KnowledgeExpand> page=new Page<>(pageNo,pageSize);
        List<KnowledgeExpand> knowledgeExpandList =knowledgeMapper.getKnowledgeExpandByName(page,knowledgeName) ;
        if (knowledgeExpandList == null || knowledgeExpandList==null) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        //根据父节点id分组
        Map<Integer, List<KnowledgeExpand>> map = knowledgeExpandList.stream().filter(o -> Objects.nonNull(o.getPid())).collect(Collectors.groupingBy(KnowledgeExpand::getPid));
        //循环处理子节点 构建树状结构
        knowledgeExpandList.forEach(o -> {
            if (map.containsKey(o.getId())) {
                o.setKnowledgeList(map.get(o.getId()));
            }
        });
        page.setRecords(knowledgeExpandList);
        return page;
    }

    @Override
    public Knowledge getKnowledgeById(Integer id) throws Exception {
        if (id == null || id <= 0) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Knowledge knowledge = new Knowledge();
        knowledge.setId(id);
        knowledge.setIsDelete(0);
        Knowledge knowledgeNew = knowledgeMapper.selectById(id);
        if (knowledgeNew == null) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        return knowledgeNew;
    }

    @Override
    public Boolean deleteKnowledgeById(Integer id) throws Exception {
        if (id == null || id <= 0) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        List<Integer> knowledgeIdList = knowledgeMapper.getKnowledgeChildren(id);
        if (knowledgeIdList != null && !knowledgeIdList.isEmpty()) {
            int count = knowledgeMapper.updateLogicallyDeleteChilders(id);
            if (count > 0) {
                return true;
            }
        }
        throw new ErrorException(ErrorCode.SYS_ERROR_NOT_AVAILABLE);
    }

    @Override
    public IPage getKnowledgeByPage(Integer pageNo, Integer pageSize) throws Exception {
        if (DataUtils.EmptyOrNegative(pageNo, pageSize)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        Page page = new Page(pageNo, pageSize);
        QueryWrapper<Knowledge> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.eq("dept", 1);
        areaQueryWrapper.eq("is_delete", 0);
        areaQueryWrapper.select("id");
        IPage knowledgePage = knowledgeMapper.selectPage(page, areaQueryWrapper);
        if (knowledgePage == null || knowledgePage.getRecords() == null || knowledgePage.getRecords().isEmpty()) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        List<Integer> knowledgeIdList = (List<Integer>) knowledgePage.getRecords().stream().map(o -> {
            Knowledge knowledge = (Knowledge) o;
            return knowledge.getId();
        }).collect(Collectors.toList());
        //查询当前接口的所有子节点
        List<KnowledgeExpand> areaList = knowledgeMapper.getKnowledgeChilderByAreaId(knowledgeIdList);
        if (areaList == null || areaList.isEmpty()) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        //根据父节点id分组
        Map<Integer, List<KnowledgeExpand>> map = areaList.stream().filter(o -> Objects.nonNull(o.getPid())).collect(Collectors.groupingBy(KnowledgeExpand::getPid));
        //循环处理子节点 构建树状结构
        areaList.forEach(o -> {
            if (map.containsKey(o.getId())) {
                o.setKnowledgeList(map.get(o.getId()));
            }
        });
        List<KnowledgeExpand> result = result = areaList.stream().filter(o -> o.getDept().equals(1)).collect(Collectors.toList());
        if (result == null || result.isEmpty()) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        knowledgePage.setRecords(result);
        return knowledgePage;
    }

    @Override
    public List<KnowledgeExpand> getKnowledgeExpand() throws Exception {
        List<KnowledgeExpand> dept1 = knowledgeMapper.getKnowledgeExpandByDept(1);
        if (DataUtils.isEmptyObject(dept1)) {
            throw new ErrorException(ErrorCode.SYS_ERROR_NULLDATE);
        }
        dept1.stream().forEach(o -> {
            List<KnowledgeExpand> dept2 = knowledgeMapper.getKnowledgeExpandByPid(o.getValue());
            dept2.stream().forEach(dept2_o -> {
                dept2_o.setKey(dept2_o.getValue());
                dept2_o.setIsLeaf(true);
            });
            o.setKnowledgeList(dept2);
            o.setKey(o.getValue());
            o.setIsLeaf(false);
        });
        return dept1;
    }

    @Override
    public List<KnowledgeExpand> getKnowledgeList() throws Exception {
        List<KnowledgeExpand> knowledgeList = knowledgeMapper.selectKnowledgeList();
        int count=0;
        for(KnowledgeExpand knowledgeExpand:knowledgeList){
            QueryWrapper<Question> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("knowledge_name",knowledgeExpand.getKnowledgeName());
            queryWrapper.eq("is_deleted",0);
            count=questionMapper.selectCount(queryWrapper);
            if(count>0){
                knowledgeExpand.setQuestionAllNum(count);
                List<Question> questionList=questionMapper.selectList(queryWrapper);
                Map<String,List<Question>> map=questionList.stream().filter(o -> Objects.nonNull(o.getQuestionType())).collect(Collectors.groupingBy(Question::getQuestionType));
                List<QuestionTypeNum> questionTypeNumList=new ArrayList<>();
                QuestionTypeNum questionTypeNum=null;
                for(Map.Entry<String,List<Question>> entry:map.entrySet()){
                    questionTypeNum=new QuestionTypeNum();
                    questionTypeNum.setQuestionType(entry.getKey());
                    questionTypeNum.setTypeQuestionNum(entry.getValue().size());
                    questionTypeNum.setTypeScore(1);
                    questionTypeNumList.add(questionTypeNum);
                }
                knowledgeExpand.setQuestionTypeNumList(questionTypeNumList);
            }else {
                knowledgeExpand.setQuestionAllNum(0);
            }
        }
        return knowledgeList;
    }

    @Override
    public AutoPaperQuestionNum getAutoPaperQuestionNumByDifficulty(String difficult, String knowledgeName) throws Exception {
        if(DataUtils.isEmpty(difficult,knowledgeName)){
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }

        QueryWrapper<Question> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("knowledge_name",knowledgeName);
        queryWrapper.eq("difficulty",difficult);
        queryWrapper.eq("is_deleted",0);
        int count=questionMapper.selectCount(queryWrapper);
        AutoPaperQuestionNum autoPaperQuestionNum=new AutoPaperQuestionNum(count,0,0,1,knowledgeName,difficult,null);
        if(count>0){
            List<Question> questionList=questionMapper.selectList(queryWrapper);
            Map<String,List<Question>> map=questionList.stream().filter(o -> Objects.nonNull(o.getQuestionType())).collect(Collectors.groupingBy(Question::getQuestionType));
            List<QuestionTypeNum> questionTypeNumList=new ArrayList<>();
            QuestionTypeNum questionTypeNum=null;
            for(Map.Entry<String,List<Question>> entry:map.entrySet()){
                questionTypeNum=new QuestionTypeNum();
                questionTypeNum.setQuestionType(entry.getKey());
                questionTypeNum.setTypeQuestionNum(entry.getValue().size());
                questionTypeNum.setTypeScore(1);
                questionTypeNumList.add(questionTypeNum);
            }
            autoPaperQuestionNum.setQuestionTypeNumList(questionTypeNumList);
        }
        return autoPaperQuestionNum;
    }


}
